import axios, { AxiosInstance, AxiosResponse } from "axios";
import { createBrowserHistory } from "history";

const history = createBrowserHistory();
// 定义请求和响应的数据接口
interface ResponseData {
  status: number;
  message: string;
  data?: unknown;
}

const service: AxiosInstance = axios.create({
  withCredentials: true, // send cookies when cross-domain requests
  timeout: 30000, // 请求不设超时时间
  headers: { "Content-Type": "application/json" },
});

// 请求拦截器
service.interceptors.request.use(
  (data) => {
    // eslint-disable-next-line no-param-reassign
    data.headers.token = window.Main.getStore("token");
    // 在发送请求之前做些什么
    return data;
  },
  (error): Promise<any> => {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse<ResponseData>): AxiosResponse<ResponseData> => {
    const res = response.data;
    if (response.status === 200 && res.status === undefined) {
      return response;
    }
    if (response.status !== 200) {
      throw new Error("未知异常");
    }
    if (res.status === 555) {
      throw new Error(res.message);
    }
    // 统一请求的异常处理
    if (res.status !== 200) {
      throw new Error(res.message);
    } else {
      return response;
    }
  },
  (error): Promise<any> => {
    let errMsg = error.response?.data?.message || "网络出错";
    if (error.response?.status === 401) {
      history.push("/login");
      errMsg = "会话过期，请重新登录";
    }
    return Promise.reject(new Error(errMsg));
  }
);

const mergeConfig = (config: any) => {
  const baseUrl = window.Main.getStore("baseUrl") as unknown as string;
  return {
    baseURL: `${baseUrl || ""}/northstar`,
    withCredentials: true,
    ...config,
  };
};
// @ts-ignore
export default  {
  get(url: string, config?: any) {
    return service.get(url, mergeConfig(config));
  },
  post(url: string, data: any, config?: Record<any, any>) {
    return service.post(url, data, mergeConfig(config));
  },
  put(data: string, config: any) {
    return service.put(data, mergeConfig(config));
  },
  delete(config: any) {
    return service.delete(mergeConfig(config));
  },
  head(url: string, config?: any) {
    return service.head(url, mergeConfig(config));
  },
};